package traveldream.ejb.sessionBean;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

import traveldream.ejb.DTO.ExcursionDTO;
import traveldream.ejb.DTO.HotelDTO;
import traveldream.ejb.DTO.PackageDTO;
import traveldream.ejb.DTO.TransportationDTO;
import traveldream.ejb.entities.DefaultPackage;
import traveldream.ejb.entities.Excursion;
import traveldream.ejb.entities.Hotel;
import traveldream.ejb.entities.TransportationMean;
import traveldream.ejb.interfaces.NotFindException;
import traveldream.ejb.interfaces.PackageInsertionBeanLocal;

/**
 * Session Bean implementation class PackageInsertionBean
 */
@Stateless
public class PackageInsertionBean implements PackageInsertionBeanLocal {

	
	@PersistenceContext
	private EntityManager em;
	
    /**
     * Default constructor. 
     */
    public PackageInsertionBean() {
        // TODO Auto-generated constructor stub
    }
    
	public void save(PackageDTO pDTO){
    	em.persist(convertFromDTO(pDTO));
    }
    
    public DefaultPackage convertFromDTO(PackageDTO pDTO){
    	DefaultPackage dP = new DefaultPackage();
    	dP.setName(pDTO.getName());
    	dP.setNation(pDTO.getNation());
    	dP.setPrice(pDTO.getPrice());
    	dP.setDescription(pDTO.getDescription());
    	dP.setHotel(em.find(Hotel.class, pDTO.getIdHotel()));
    	dP.setExcursion(em.find(Excursion.class, pDTO.getIdExcursion()));
    	dP.setTransport_arr(em.find(TransportationMean.class, pDTO.getIdReturn()));
    	dP.setTransport_dep(em.find(TransportationMean.class, pDTO.getIdGoing()));
    	dP.setInvalid(false);
    	return dP;
    }
    
    public List<HotelDTO> allHotel(){
    	List<Hotel> hotels = em.createNamedQuery(Hotel.FIND_ALL).getResultList();
    	List<HotelDTO> hDTO = new ArrayList<HotelDTO>();
    	
    	for(Hotel h : hotels){
    		hDTO.add(h.convertToDTO());
    	}
    	return hDTO;
    }
    
    public List<ExcursionDTO> allExcursion(){
    	List<Excursion> excursions = em.createNamedQuery(Excursion.FIND_ALL).getResultList();
    	List<ExcursionDTO> eDTO = new ArrayList<ExcursionDTO>();
    	
    	for(Excursion e : excursions){
    		eDTO.add(e.convertToDTO());
    	}
    	return eDTO;
    }
    
    public List<TransportationDTO> allTransport() {
		List<TransportationMean> t=em.createNamedQuery(TransportationMean.FIND_ALL).getResultList();
		List<TransportationDTO> tDTO = new ArrayList<TransportationDTO>();
		for(int i=0;i<t.size();i++)
		{
			tDTO.add(t.get(i).convertToDTO());
		}
		return tDTO;
	}
 
	   
    public boolean checkPackage(int selectedH,int selectedE, int selectedG, int selectedR) throws NotFindException{
		String cityHotel = "a",cityGoingD="b",cityGoingA="c",cityReturnA="d",cityReturnD="e",cityExcursion="f";
		Date dateReturnA = new Date(), dateGoingA = new Date();
		Date dateReturnD = new Date(),dateGoingD = new Date();
		
		System.out.println(selectedH);
		//take the city of the hotel
		cityHotel = em.find(Hotel.class, selectedH).getCity();
		
		//take the city of the excursion
		try{
		cityExcursion = em.find(Excursion.class, selectedE).getCity();
		}
		catch(NullPointerException e){
			if(selectedE>0)
				throw new NotFindException();
			else
				cityExcursion=cityHotel;
		}
		//take the cities of the departure and arrival transportation
		TransportationMean goingTransport = em.find(TransportationMean.class, selectedG);
		TransportationMean returnTransport = em.find(TransportationMean.class, selectedR);
		cityReturnA = returnTransport.getArrival_Place();
		cityReturnD = returnTransport.getDeparture_Place();
		dateReturnA = returnTransport.getArrival_Date();
		dateReturnD = returnTransport.getDeparture_Date();
		cityGoingA = goingTransport.getArrival_Place();
		cityGoingD = goingTransport.getDeparture_Place();
		dateGoingD = goingTransport.getDeparture_Date();
		dateGoingA = goingTransport.getArrival_Date();
		
		//check if the package is consistent
		return (cityHotel.equals(cityExcursion) && cityReturnA.equals(cityGoingD) && cityReturnD.equals(cityGoingA)
				&& cityHotel.equals(cityGoingA) && dateGoingA.compareTo(dateReturnD) < 0);
		
	}
    
    public long dayBetweenTwoDate(Date uno, Date due) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(uno);
		c2.setTime(due);

		long giorni = (c2.getTime().getTime() - c1.getTime()
				.getTime())	/ (24 * 3600 * 1000);

		return giorni;
	}


	@Override
	public boolean checkPrice(int selectedH, int selectedE, int selectedG,
			int selectedR, PackageDTO pDTO) throws NotFindException{
		TransportationMean g,r;
		int price;
		g = em.find(TransportationMean.class, selectedG);
		r = em.find(TransportationMean.class, selectedR);
		try{
			price = em.find(Hotel.class, selectedH).getPrice()*((int) dayBetweenTwoDate(g.getArrival_Date(),r.getDeparture_Date())) + em.find(Excursion.class, selectedE).getPrice() +
					g.getPrice() + r.getPrice();
			System.out.println("durante il check: "+price);
			return pDTO.getPrice()<=price;
		}
		catch(NullPointerException e){
			if(selectedE>0)
				throw new NotFindException();
			else{
				price =(em.find(Hotel.class, selectedH).getPrice()*((int) dayBetweenTwoDate(g.getArrival_Date(),r.getDeparture_Date())) + 0 + em.find(TransportationMean.class, selectedG).getPrice() + em.find(TransportationMean.class, selectedR).getPrice());
				System.out.println("durante il check: "+price);
				return  pDTO.getPrice()<= price;
			}
		}
	}
    
    
}
